const fs = require('fs')
const path = require('path')

class Controller {
  constructor(req, res, app) {
    this.req = req
    this.res = res
    this.app = app
  }
}

exports.Controller = Controller

const loadController = controllerPath => {
  const controllerMap = {} // 保存所有控制器
  const files = fs.readdirSync(controllerPath) // 读取目录
  files.forEach(file => {
    const fileState = fs.statSync(path.join(controllerPath, file)) // 文件信息
    // 文件目录
    if (fileState.isDirectory()) {
      controllerMap[file] = {
        isDir: true,
        ...loadController(path.join(controllerPath, file)) // 再次递归
      }
    } else {
      // 文件
      const controllerName = file.substr(0, file.lastIndexOf('.')) // 获取文件名称
      if (controllerName) {
        controllerMap[controllerName] = {
          isDir: false,
          value: require(path.join(controllerPath, file)) // 引入文件
        }
      }
    }
  })
  return controllerMap
}

const errMsg = message => ({ code: 1, message, data: null })
const createProxy = (controllerMap, app) => {
  return new Proxy(controllerMap, {
    get(target, name) {
      if (target[name]) {
        if (!target[name].isDir) {
          return new Proxy(target[name], {
            get(target, name) {
              return (req, res) => {
                if(Object.getOwnPropertyNames(target.value.prototype).includes(name)) {
                  new target.value(req, res, app)[name]()
                } else {
                  res.send(errMsg('method not found'))
                }
              }
            }
          })
        } else {
          // 文件目录
          return createProxy(target[name], app)
        }
      } else {
        // 名称不存在
        return new Proxy({}, {
          get(target, name) {
            return (req, res) => {
              res.send(errMsg('controller not found'))
            }
          }
        })
      }
    }
  })
}

const controllerMap = loadController(path.join(__dirname, '../controller'))

module.exports = app => {
  app.controller = createProxy(controllerMap, app)
  return (req, res, next) => {
    next()
  }
}


// const fs = require('fs')
// const path = require('path')

// class Controller {
//   constructor(req, res, app) {
//     this.req = req
//     this.res = res
//     this.app = app
//   }
// }

// exports.Controller = Controller

// const loadController = controllerPath => {
//   const controllerMap = {}
//   const files = fs.readdirSync(controllerPath)
//   files.forEach(file => {
//     const fileState = fs.statSync(path.join(controllerPath, file))
//     if (fileState.isDirectory()) {
//       controllerMap[file] = {
//         isDir: true,
//         ...loadController(path.join(controllerPath, file))
//       }
//     } else {
//       const controllerName = file.substr(0, file.lastIndexOf('.'))
//       if (controllerName) {
//         controllerMap[controllerName] = {
//           isDir: false,
//           value: require(path.join(controllerPath, file))
//         }
//       }
//     }
//   })
//   return controllerMap
// }

// const errMsg = message => ({ code: 1, message, data: null })
// const createProxy = (controllerMap, app) => {
//   return new Proxy(controllerMap, {
//     get(target, name) {
//       if (target[name]) {
//         if (!target[name].isDir) {
//           return new Proxy(target[name], {
//             get(target, name) {
//               return (req, res) => {
//                 if (Object.getOwnPropertyNames(target.value.prototype).includes(name)) {
//                   new target.value(req, res, app)[name]()
//                 } else {
//                   res.send(errMsg('method not exist'))
//                 }
//               }
//             }
//           })
//         } else {
//           return createProxy(target[name], app)
//         }
//       } else {
//         return new Proxy({}, {
//           get() {
//             return (req, res) => {
//               res.send(errMsg('controller not exist'))
//             }
//           }
//         })
//       }
//     }
//   })
// }

// const controllerMap = loadController(path.join(__dirname, '../controller'))

// module.exports = app => {
//   app.controller = createProxy(controllerMap, app)
//   return (req, res, next) => {
//     next()
//   }
// }
